#ifndef _RULES_H_
#define _RULES_H_

#include <string>
#include <vector>

namespace lang
{

class RuleData;

class Rules
{
public:
	static Rules&	Instance();
	void			SetLanguage(const std::string& Lang);
	int				ApplyRules(const std::wstring& Buffer, int From, int To);

private:
	Rules();
	virtual ~Rules();

	RuleData*		m_pRule;
	std::string		m_CurrentLanguage;
};

class RuleData
{
public:
	RuleData() : m_JumpToIndex(-1) {}
	virtual ~RuleData() {}

	virtual int		ApplyRules(const std::wstring& Buffer, int From, int To);

protected:
	virtual bool	CanBreakHere(const std::wstring& Buffer, int Idx) = 0;
	bool			IsInList(unsigned short ch, unsigned short* pList, int Count);
	void			SetJumpIndex(int idx) { m_JumpToIndex = idx; }

private:
	int				m_JumpToIndex;
};

class Rule_KinsokuShori : public RuleData
{
public:
	Rule_KinsokuShori();
	virtual ~Rule_KinsokuShori() {}

protected:
	virtual bool	CanBreakHere(const std::wstring& Buffer, int Idx);
	bool			IsKanji(unsigned short ch);
	bool			IsHiragana(unsigned short ch);
	bool			IsKatakana(unsigned short ch);
	bool			IsKana(unsigned short ch)	{ return IsHiragana(ch) || IsKatakana(ch); }

private:
	std::vector<std::wstring>	m_GrammaticalHiragana;
	bool			IsGrammaticalHiragana(const std::wstring& Buffer, int Idx);
};

class Rule_GenericLatin : public RuleData
{
public:
	Rule_GenericLatin() {}
	virtual ~Rule_GenericLatin() {}

protected:
	virtual bool	CanBreakHere(const std::wstring& Buffer, int Idx);
};

}  //namespace lang

#endif //_RULES_H_
